﻿
#include "trading_section.h"
#include <define.h>
#include <rapidcsv.h>
#include "log_wapper.hpp"
#include <time_utils.hpp>

// 构造函数：从配置文件中读取交易时段信息，并初始化 _trading_section
trading_section::trading_section(const std::string& config_path) noexcept
{
    // 记录日志，表明交易时段初始化开始
	LOG_INFO("trading_section init ");
	
    // 清空 _trading_section 向量，确保不会有旧数据
	_trading_section.clear();
    
    // 使用 rapidcsv 库加载 CSV 配置文件
	rapidcsv::Document config_csv(config_path, rapidcsv::LabelParams(0, 0));
	
    // 遍历 CSV 文件的每一行，读取交易时段的开始和结束时间
	for (size_t i = 0; i < config_csv.GetRowCount(); i++)
	{
		// 从 CSV 中读取开始时间和结束时间的字符串表示
		const std::string& begin_time_str = config_csv.GetCell<std::string>("begin", i);
		const std::string& end_time_str = config_csv.GetCell<std::string>("end", i);
		
        // 将时间字符串转换为 daytm_t 类型的时间戳
		daytm_t begin_time = make_daytm(begin_time_str.c_str(), 0U);
		daytm_t end_time = make_daytm(end_time_str.c_str(), 0U);
		
        // 将开始时间和结束时间作为一个 pair 加入到 _trading_section 向量中
		_trading_section.emplace_back(std::make_pair(begin_time, end_time));
		
        // 可以在这里输出调试信息，查看每个交易时段的开始和结束时间
		// LOG_DEBUG("trading_section : ", time_to_string(begin_time), time_to_string(end_time));
	}
}

// 析构函数：目前没有需要特别处理的资源释放操作
trading_section::~trading_section() noexcept
{
	// 析构函数没有特别的实现内容，但保留此函数用于保证正确的析构链
}

// 检查某个时间点是否在交易时段内
bool trading_section::is_in_trading(daytm_t last_time) noexcept
{
	// LOG_TRACE("trading_section is_in_trading : %s ", datetime_to_string(last_time).c_str());

    // 遍历所有的交易时段，检查给定的时间点是否在某个交易时段内
	for(const auto& it: _trading_section)
	{
		// 如果给定时间在交易时段的开始和结束时间之间，则返回 true
		if(it.first <= last_time && last_time < it.second)
		{
			return true;
		}
	}
	
    // 如果给定时间不在任何交易时段内，返回 false
	return false;
}

// 获取当前交易时段的开盘时间
daytm_t trading_section::get_open_time() noexcept
{
    // 获取交易时段的第一个元素，即第一个开盘时间
	auto frist_one = _trading_section.begin();
	
    // 如果交易时段为空，返回 0
	if (frist_one == _trading_section.end())
	{
		return 0;
	}
	
    // 返回第一个交易时段的开盘时间
	return frist_one->first;
}

// 获取当前交易时段的收盘时间
daytm_t trading_section::get_close_time() noexcept
{
    // 获取交易时段的最后一个元素，即最后一个收盘时间
	auto last_one = _trading_section.rbegin();
	
    // 如果交易时段为空，返回 0
	if(last_one == _trading_section.rend())
	{
		return 0;
	}
	
    // 返回最后一个交易时段的收盘时间
	return last_one->second;
}

// 根据当前时间获取下一次的开盘时间
daytm_t trading_section::next_open_time(daytm_t now) noexcept
{
    // 从当前交易时段中找到与当前时间相匹配的索引
	size_t i = 0;
	for(; i < _trading_section.size(); i++)
	{
		// 如果当前时间小于或等于某个交易时段的开盘时间，停止循环
		if(_trading_section[i].first <= now)
		{
			break;
		}
	}
	
    // 从找到的索引开始，查找下一个交易时段的开盘时间
	for (size_t j = i; j < i + _trading_section.size(); j++)
	{
		auto iter = _trading_section[j % _trading_section.size()];
		
        // 如果当前时间早于找到的某个交易时段的开盘时间，返回该开盘时间
		if(now < iter.first)
		{
			return iter.first;
		}
	}
	
    // 如果找不到符合条件的交易时段，返回 0
	return 0U;
}

//